#ifndef AVALON_AESENCODER_HPP
#define AVALON_AESENCODER_HPP
#include <boost/scoped_array.hpp>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/secblock.h>
#include "Avalon/Codecs/Encoder.hpp"

namespace Avalon {
namespace Codecs {

  /*! \class AesEncoder
   *  \brief Encodes using AES-256 encryption.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class AesEncoder : public Encoder {
    public:

      //! Constructs an AesEncoder.
      /*!
        \param key The encryption key.
        \param iv The encryption iv.
      */
      AesEncoder(const CryptoPP::SecByteBlock& key, const byte* iv);

      virtual ~AesEncoder();

      virtual bool IsEncodeInPlaceSupported();

      virtual void Encode(const void* source, int sourceSize,
        void* destination, int destinationSize, int* encodedSize = NULL);

      virtual void Encode(const void* source, int sourceSize,
        IO::Buffer* destination, int* encodedSize = NULL);

      using Encoder::Encode;

      using Encoder::EncodeInPlace;

    private:
      CryptoPP::SecByteBlock m_key;
      boost::scoped_array<byte> m_iv;
      CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption m_encoder;
  };
}
}

#endif // AVALON_AESENCODER_HPP
